﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
using Delay;

namespace lfm.Parser
{
    internal class Track
    {
        public static async Task<lfm.Track> getInfo(String e)
        {
            lfm.Track result = new lfm.Track();

            // Make Method Run Asynchronously
            await Task.Run(() =>
            {
                XDocument x = XDocument.Parse(e);

                // Parse main artist details
                result = (from u in x.Descendants("track")
                          select new lfm.Track
                          {
                              Name = u.SafeGetElement("name").SafeGetStringValue(),
                              ID = u.SafeGetElement("id").SafeGetInt64Value(),
                              URL = u.SafeGetElement("url").SafeGetUriValue(),
                              Duration = u.SafeGetElement("duration").SafeGetInt64Value(),
                              Streamable = Converters.ToBool(u.SafeGetElement("streamable").SafeGetStringValue()),
                              FullTrack = Converters.ToBool(u.SafeGetElement("streamable").SafeGetAttribute("fulltrack").SafeGetStringValue()),
                              Listeners = u.SafeGetElement("listeners").SafeGetInt64Value(),
                              Playcount = u.SafeGetElement("playcount").SafeGetInt64Value(),
                              Artist = new lfm.Artist
                              {
                                  Name = u.SafeGetElement("artist").SafeGetElement("name").SafeGetStringValue(),
                                  Url = u.SafeGetElement("artist").SafeGetElement("url").SafeGetUriValue()
                              },
                              AlbumPosition = u.SafeGetElement("album").SafeGetAttribute("rank").SafeGetInt32Value(),
                              Album = new lfm.Album
                              {
                                  Name = u.SafeGetElement("album").SafeGetElement("title").SafeGetStringValue(),
                                  URL = u.SafeGetElement("album").SafeGetElement("url").SafeGetUriValue(),
                                  ImageSmall = u.SafeGetElement("album").Elements("image").Where(n => n.SafeGetAttribute("size").SafeGetStringValue() == "small").FirstOrDefault().SafeGetUriValue(),
                                  ImageMedium = u.SafeGetElement("album").Elements("image").Where(n => n.SafeGetAttribute("size").SafeGetStringValue() == "medium").FirstOrDefault().SafeGetUriValue(),
                                  ImageLarge = u.SafeGetElement("album").Elements("image").Where(n => n.SafeGetAttribute("size").SafeGetStringValue() == "large").FirstOrDefault().SafeGetUriValue(),
                                  ImageExtraLarge = u.SafeGetElement("album").Elements("image").Where(n => n.SafeGetAttribute("size").SafeGetStringValue() == "extralarge").FirstOrDefault().SafeGetUriValue()
                              },
                              TopTags = new List<lfm.Tag>(),
                              WikiPublished = u.SafeGetElement("wiki").SafeGetElement("published").SafeGetDateTimeValue(DateTime.Now),
                              WikiSummary = u.SafeGetElement("wiki").SafeGetElement("summary").SafeGetStringValue(),
                              WikiContent = u.SafeGetElement("wiki").SafeGetElement("content").SafeGetStringValue()
                          }).FirstOrDefault();
            });

            // Parse the tag list
            foreach (var t in await Generic.getTags(e)) result.TopTags.Add(t);

            // return the full artists
            return result;
        }

        public static async Task<List<lfm.Track>> getSimilar(String e)
        {
            List<lfm.Track> result = new List<lfm.Track>();

            // Make Method Run Asynchronously
            await Task.Run(() =>
            {
                XDocument x = XDocument.Parse(e);

                // Parse main artist details
                var results = from u in x.Descendants("track")
                              select new lfm.Track
                              {
                                  Name = u.SafeGetElement("name").SafeGetStringValue(),
                                  Match = Converters.ToDouble(u.SafeGetElement("match").SafeGetStringValue()),
                                  Playcount = u.SafeGetElement("playcount").SafeGetInt64Value(),
                                  URL = u.SafeGetElement("url").SafeGetUriValue(),
                                  AlbumPosition = u.SafeGetElement("album").SafeGetAttribute("rank").SafeGetInt32Value(),
                                  Duration = u.SafeGetElement("duration").SafeGetInt64Value(),
                                  Streamable = Converters.ToBool(u.SafeGetElement("streamable").SafeGetStringValue()),
                                  FullTrack = Converters.ToBool(u.SafeGetElement("streamable").SafeGetAttribute("fulltrack").SafeGetStringValue()),
                                  Artist = new lfm.Artist
                                  {
                                      Name = u.SafeGetElement("artist").SafeGetElement("name").SafeGetStringValue(),
                                      Url = u.SafeGetElement("artist").SafeGetElement("url").SafeGetUriValue()
                                  },
                                  Album = new lfm.Album
                                  {
                                      ImageSmall = u.Elements("image").Where(n => n.SafeGetAttribute("size").SafeGetStringValue() == "small").FirstOrDefault().SafeGetUriValue(),
                                      ImageMedium = u.Elements("image").Where(n => n.SafeGetAttribute("size").SafeGetStringValue() == "medium").FirstOrDefault().SafeGetUriValue(),
                                      ImageLarge = u.Elements("image").Where(n => n.SafeGetAttribute("size").SafeGetStringValue() == "large").FirstOrDefault().SafeGetUriValue(),
                                      ImageExtraLarge = u.Elements("image").Where(n => n.SafeGetAttribute("size").SafeGetStringValue() == "extralarge").FirstOrDefault().SafeGetUriValue()
                                  }
                              };

                foreach (lfm.Track t in results) result.Add(t);
            });

            // return the full artists
            return result;
        }

        public static async Task<List<lfm.Track>> search(String e)
        {
            List<lfm.Track> result = new List<lfm.Track>();

            // Make Method Run Asynchronously
            await Task.Run(() =>
            {
                XDocument x = XDocument.Parse(e);

                // Parse main artist details
                var results = from u in x.Descendants("track")
                              select new lfm.Track
                              {
                                  Name = u.SafeGetElement("name").SafeGetStringValue(),
                                  Artist = new lfm.Artist
                                  {
                                      Name = u.SafeGetElement("artist").SafeGetStringValue()
                                  },
                                  URL = u.SafeGetElement("url").SafeGetUriValue(),
                                  Streamable = Converters.ToBool(u.SafeGetElement("streamable").SafeGetStringValue()),
                                  FullTrack = Converters.ToBool(u.SafeGetElement("streamable").SafeGetAttribute("fulltrack").SafeGetStringValue()),
                                  Listeners = u.SafeGetElement("listeners").SafeGetInt64Value(),
                                  Album = new lfm.Album
                                  {
                                      ImageSmall = u.Elements("image").Where(n => n.SafeGetAttribute("size").SafeGetStringValue() == "small").FirstOrDefault().SafeGetUriValue(),
                                      ImageMedium = u.Elements("image").Where(n => n.SafeGetAttribute("size").SafeGetStringValue() == "medium").FirstOrDefault().SafeGetUriValue(),
                                      ImageLarge = u.Elements("image").Where(n => n.SafeGetAttribute("size").SafeGetStringValue() == "large").FirstOrDefault().SafeGetUriValue(),
                                      ImageExtraLarge = u.Elements("image").Where(n => n.SafeGetAttribute("size").SafeGetStringValue() == "extralarge").FirstOrDefault().SafeGetUriValue()
                                  }
                              };

                foreach (lfm.Track t in results) result.Add(t);
            });

            // return the full artists
            return result;
        }
    }
}
